package com.di.base.config;

import com.alibaba.cloud.commons.lang.StringUtils;
import com.di.base.common.exception.BusinessException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import feign.Client;
import feign.Logger;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import feign.codec.ErrorDecoder;
import feign.form.spring.SpringFormEncoder;
import io.seata.core.context.RootContext;
import io.seata.saga.engine.serializer.impl.ExceptionSerializer;
import org.springframework.boot.CommandLineRunner;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.cloud.openfeign.support.SpringEncoder;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StreamUtils;

import java.beans.Encoder;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;

@Configuration
public class SeataFeignConfiguration implements RequestInterceptor {
    @Bean
    public RequestInterceptor seataRequestInterceptor() {
        return template -> {
            String xid = RootContext.getXID();
            if (StringUtils.isNotBlank(xid)) {
                template.header(RootContext.KEY_XID, xid);
            }
        };
    }
    @Override
    public void apply(RequestTemplate template) {
        String xid = RootContext.getXID();
        if (xid != null) {
            template.header(RootContext.KEY_XID, xid);
        }
    }

    @Bean
    public Client feignClient() {
        return new Client.Default(null, null);
    }

    @Bean
    public CommandLineRunner runner(ApplicationContext context) {
        return args -> {
            for (String name : context.getBeanDefinitionNames()) {
                if (name.toLowerCase().contains("storage") || name.toLowerCase().contains("account")) {
                    System.out.println("beanName => " + name);
                }
            }
        };
    }

    @Bean
    public CommandLineRunner runners(ApplicationContext context) {
        return args -> {
            System.out.println("===== Feign相关Bean列表 =====");
            Arrays.stream(context.getBeanNamesForType(FeignClient.class))
                    .forEach(name -> System.out.println("Feign Bean: " + name));
        };
    }
    @Bean
    public ErrorDecoder errorDecoder() {
        return (methodKey, response) -> {
            // 解析响应体
            String body;
            try (InputStream inputStream = response.body().asInputStream()) {
                body = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
            } catch (IOException e) {
                throw new RuntimeException("Failed to process response body", e);
            }

            try {
                // 尝试解析为自定义异常
                ObjectMapper mapper = new ObjectMapper();
                JsonNode rootNode = mapper.readTree(body);
                Integer code = rootNode.path("code").asInt();
                String message = rootNode.path("message").asText();
                return new BusinessException(code, message);
            } catch (IOException e) {
                // 解析失败，返回通用客户端异常
                return new BusinessException(500, "客户端错误: " + body);
            }
        };
    }
}
